import random
import time
from math import sqrt 

#Daniel Brownell Hunger Games Competition Entry
class Player:
    def __init__(self):
        
        random.seed(time.time());
        self.sorted_reputation_list = []
        
        
    def naive_variance(self, data):
        n = 0
        Sum = 0
        Sum_sqr = 0
     
        for x in data:
            n = n + 1
            Sum = Sum + x
            Sum_sqr = Sum_sqr + x*x
     
        variance = (Sum_sqr - ((Sum*Sum)/n))/(n - 1)
        return variance

    def indexOf(self, data, lookup):

        for i in range(len(data)):
            if (data[i] == lookup):
                return i;
            
        return -1

                                              # R = H/(H + S)
    def hunt_choices(self, round_number, current_food, current_reputation, m, player_reputations):
        
        self.sorted_reputation_list = player_reputations[:]
        self.sorted_reputation_list.sort();
        self.sorted_reputation_list.reverse();

        sumreps = sum(player_reputations)
        avgreps = sumreps / len(player_reputations)
        variance = self.naive_variance(player_reputations)
        stddev = sqrt(variance)
        P = len(player_reputations)


        #automatically hunt with the best 5% and slack with the worst 5%
        goodindexthreshold = math.floor(0.05*P)
        badindexthreshold = math.ceil(0.95*P) - 1
        #automatically hunt with the very cooperative
        #automatically slack with the very defective
        highthreshold = avgreps + 1.5*stddev
        lowthreshold = avgreps - 1.5*stddev

        #get a slightly better rep in the beginning to maybe be more trustworthy
        #than the average, and get into a high threshold group 
        good_rep_bonus = 2**-round_number

        #don't know what to do with m
        #but if it's super close, hunt with a few of the more trustworthy
        if (m > (P*(P - 1)*avgreps) and m < (P*(P - 1)*avgreps) + P):
            highthreshold = avgreps + 1.4*stddev 

        
        hunt_decisions = list()

        #I determined ahead of time, with a monte carlo simulation that in the
        #very long run, you should hunt with someone exactly as much as their
        #reputation suggests you should.  Even small deviations from this will
        #hurt you in the long run.  But I presume there will be some smart people
        #in this competition who actually track their opponents reputations, and try 
        #work out the strategy of their opponent.  if that's the case, random
        #defections might turn them against you unnecessarily.  So I added some
        #threshold code, as that may be useful against others who are very cooperative.
        for i in range(P):
            index = self.indexOf(self.sorted_reputation_list, player_reputations[i])

            #hunt with everyone first round to get better reputation
            if (round_number <= 1):
                hunt_decisions.append('h')
            elif (badindexthreshold <= index):
                hunt_decisions.append('s')
            elif (goodindexthreshold >= index):
                hunt_decisions.append('h')
            elif (lowthreshold > player_reputations[i]):
                hunt_decisions.append('s')
            elif (highthreshold < player_reputations[i]):
                hunt_decisions.append('h')
            elif (random.random() <= player_reputations[i] + good_rep_bonus):
                hunt_decisions.append('h')
            else:
                hunt_decisions.append('s')
        
        return hunt_decisions

    def hunt_outcomes(self, food_earnings):
        pass

    def round_end(self, award, m, number_hunters):
        pass

